package cn.le.crawler.gpw;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.le.annotation.CrawlerName;
import cn.le.crawler.AbstractCrawler;
import cn.le.crawler.Crawler;
import cn.le.entity.CrawlerHome;
import cn.le.enums.EnumCrawler;
import cn.le.enums.EnumHomeStatus;
import com.alibaba.fastjson.JSON;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;


/**
 * @Description 公拍网
 * @Author le
 * @Date 2020/4/12 11:45
 * @Version 0.1
 **/
@Component
@CrawlerName(value = EnumCrawler.Gpw)
public class GPWHomeCrawler extends AbstractCrawler implements Crawler {

    /**
     * 爬取房源
     * @return
     */
    public List<CrawlerHome> crawlerHome() throws Exception {
        List<String> urls = GPWPropertyUtil.getUrls();
        CompletionService<List<GPWData>> homeCs = new ExecutorCompletionService<List<GPWData>>(executor);
        //抓取房源数据
        urls.forEach(url->{
            homeCs.submit(new Callable<List<GPWData>>() {
                @Override
                public List<GPWData> call() throws Exception {
                    Document document = getDocument(url);
                    List<GPWData> list = parsingData(document);
                    return list;
                }
            });
        });
        //并发抓取房源图片和报名人数
        CompletionService<GPWData> homeProfileCs = new ExecutorCompletionService<GPWData>(executor);
        int index = 0;
        for (int i = 0,size = urls.size(); i < size; i++) {
            List<GPWData> list = homeCs.take().get();
            if (CollectionUtils.isEmpty(list)){
                continue;
            }
            list.forEach(data -> {
                homeProfileCs.submit(new Callable<GPWData>() {
                    @Override
                    public GPWData call() throws Exception {
                        Document document  = getDocument(data.getItemUrl());
                        parsingHomeImg(data,document);
                        parsingBidCount(data,document);
                        return data;
                    }
                });
            });
            index += list.size();
        }
        List<CrawlerHome> crawlerHomes = new LinkedList<>();
        for (int i = 0,size = index; i < size; i++) {
            GPWData gpwData = homeProfileCs.take().get();
            CrawlerHome crawlerHome = mapperCrawlerHome(gpwData);
            crawlerHomes.add(crawlerHome);
        }
        return crawlerHomes;
    }


    private static CrawlerHome mapperCrawlerHome(GPWData gpwData){
        CrawlerHome crawlerHome = new CrawlerHome();
        BeanUtil.copyProperties(gpwData,crawlerHome);
        return crawlerHome;
    }


    private static void parsingHomeImg(GPWData data,Document document) throws IOException {
        Elements elements = document.select("div.richtext").select("img");
        List<String> homeImgs = new ArrayList<>();
        elements.forEach(element -> {
            String homeImg = element.attr("src");
            homeImgs.add(homeImg);
        });
        data.setHomeImgs(JSON.toJSONString(homeImgs));
    }

    private static void parsingBidCount(GPWData data,Document document){
        Elements elements = document.select("div.peoples-infos").select("span b");
        try {
            data.setBidCount(Integer.valueOf(elements.get(0).text()));
        }catch (Exception e){
            return;
        }

    }

    /**
     * 返回值解析
     * @param document
     * @return
     */
    private static List<GPWData> parsingData(Document document){
        List<GPWData> gpwDataList = new LinkedList<>();
        Elements contextElement = document.select("div.list-item");
        for (Element context : contextElement) {
            GPWData gpwData = new GPWData();
            //状态
            String status = context.getElementsByClass("badge-icon").text();
            EnumHomeStatus homeStatus = EnumHomeStatus.GPWStatus.getByCode(status);
            gpwData.setStatus(homeStatus.getText());
            //标题
            String title = context.select("div.item-tit").select("a[href]").text();
            gpwData.setTitle(title);
            //封面
            String cover =context.select("img").attr("src");
            gpwData.setCover(cover);
            //item -url
            String itemUrl =  context.select("div.item-tit").select("a[href]").attr("href");
            gpwData.setItemUrl(itemUrl);
            //起拍价
            String initialPrice = context.select("div.gpai-infos").select("b.price-red").text().replace("--","");
            try {
                initialPrice = StringUtils.isEmpty(initialPrice) ? "0" : initialPrice;
                gpwData.setInitialPrice(Double.valueOf(initialPrice));
            }catch (Exception e){
                e.printStackTrace();
            }

            //评估价
            String consultPrice = context.select("div.gpai-infos").select("span b").text();
            consultPrice = consultPrice.replace(",","");
            //评估价单位
            String unit  = context.select("div.gpai-infos").select("span").text();
            Double price = 0D;
            if (unit.indexOf("万") > 0){
                price = Double.valueOf(consultPrice) * 10000;
            }else {
                price = Double.valueOf(consultPrice);
            }
            gpwData.setConsultPrice(price);
            //结束时间
            String date = context.select("div.gpai-infos").select("p").get(4).select("span").text();
            if (EnumHomeStatus.Todo.equals(homeStatus)){
                date = date.replace("开始时间：","").trim();
                gpwData.setStart(DateUtil.parse(date,"yyyy-MM-dd HH:mm:ss"));
            }else if (StringUtils.isEmpty(date)){
            }else {
                date = date.replace("结束时间：","").replace("预计结束：","").trim();
                try {
                    gpwData.setEnd(DateUtil.parse(date,"yyyy-MM-dd HH:mm:ss"));
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            //围观人数
            String viewerCount = context.select("div.m-infos-people").select("div.whalf").get(0).text();
            try {
                viewerCount = viewerCount.replace("次围观","").replace("次出价","").trim();
                gpwData.setViewerCount(Integer.valueOf(viewerCount));
            }catch (Exception e){
                e.printStackTrace();
                System.out.println(viewerCount);
            }
            String homeId = itemUrl.substring(itemUrl.indexOf("=") + 1,itemUrl.length());
            try {
                gpwData.setHomeId(Long.parseLong(homeId));
            }catch (Exception e){
                e.printStackTrace();
            }

            gpwDataList.add(gpwData);
        }
        return gpwDataList;
    }
}
